package cc.minos.game.go.reader
{
	import cc.minos.game.go.node.SGFNode;
	import cc.minos.game.go.node.SGFTree;
	import cc.minos.game.go.node.SGFVO;
	import cc.minos.game.go.SGFUtil;
	import cc.minos.utils.ArrayUtil;
	
	/**
	 * ...
	 * @author Minos
	 */
	public class ReaderSGF extends ReaderBase
	{
		
		public function ReaderSGF()
		{
			super();
		}
		
		override public function setSGF(tree:SGFTree, s:String):void 
		{
			tree.isSinaSGF = false;
			tree.isVar = false;
			rootTree = tree;
			sgf = s;
			nextToken();
			execSgf( tree.root , LAX_SGF , tree );
			rootTree.lastNode = rootTree.root;
		}
		
		override public function getRoads():Array 
		{
			_roads = [];
			getRoad( rootTree.root );
			return _roads;
		}
		
		private function getRoad( node:SGFNode , pre:Array = null ):void
		{
			var ary:Array = [];
			_roads.push( ary );
			if ( pre != null )
				ArrayUtil.merge( ary , pre );
			while ( node.child )
			{
				if ( node.trees && node.trees.length > 0)
				{
					for ( var i:int = 0, len:int = node.trees.length; i < len; i++) {
						var t:SGFTree = node.trees[i];
						getRoad( t.root , ary );
					}
				}
				node = node.child;
				var vo:SGFVO = new SGFVO();
				vo.nodeColor = node.nodeColor;
				vo.nodeX = node.nodeX;
				vo.nodeY = node.nodeY;
				vo.comment = node.comment;
				ary.push( vo );
			}
		}
		
		private function checkPos( s:String ):Boolean
		{
			if ( s!=null && s.length == 1 )
			{
				if ( s >= "A" && s <= "Z" )
				{
					return true;
				}
			}
			return false;
		}
		
		private function execSgf( node:SGFNode , format:String , tree:SGFTree ):void
		{
			var tmp:SGFNode;
			if ( format == STRICT_SGF )
			{
				toNext("(");
			}else
			{
				while (true)
                {
                    
                    if (head == EOF)
                    {
                        trace("data error");
                        break;
                    }
                    if (head == "(")
                    {
                        while (head == "(")
                        {
                            nextToken();
                        }
                        if (head == ";")
                        {
                            break;
                        }
                    }
                    nextToken();
                }
			}
			
			if (node.isRootNode() && !node.isParsered && !isParsered)
            {
                tmp = node;
                isParsered = true;
            }
            else
            {
                tmp = new SGFNode( node );
            }
            var cNode:SGFNode = execNodeTree(tmp);
			
            var cTree:SGFTree = null;
            while (head == "(")
            {
                
                if (!cTree)
                {
                    execSgf(cNode, STRICT_SGF, null);
                }
                else
                {
                    execSgf(cTree.root, STRICT_SGF, cTree);
                }
                if (head == "(")
                {
                    cTree = new SGFTree(tree );
                    cTree.isVar = true;
					cTree.lastNode = cNode;
                    cNode.trees.push(cTree);
					//
					//trace( cNode );
					//
                }
            }
			
			if ( format == STRICT_SGF )
			{
				toNext(")");
			}
			
		}
		
		private function execNodeTree( node:SGFNode ):SGFNode
		{
			var tmp:SGFNode;
			execNode( node );
			while ( head == ";" )
			{
				tmp = new SGFNode( node );
				node = tmp;
				execNode( node );
			}
			return node;
		}
		
		private function execNode( node:SGFNode ):void
		{
			var index:int;
			var prop:String;
			var data:String;
			var ary:Array;
			var preStr:String;
			
			node.isParsered = true;
			toNext( ";" );
			while ( head != EOF && checkPos( head ) )
			{
				index = sgf.indexOf( "[" , sgfIndex );
				prop = sgf.substr( sgfIndex , index - sgfIndex );
				sgfIndex = sgfIndex + prop.length + 1;
				index = sgf.indexOf( "]" , sgfIndex );
				while ( sgf.charAt(( index - 1 ) ) == "\\" )
				{
					index = sgf.indexOf( "]" , ( index + 1 ) );
				}
				data = sgf.substr( sgfIndex , index - sgfIndex );
				sgfIndex = sgfIndex + data.length;
				ary = data.split( "\\" );
				if ( ary.length > 1 )
				{
					data = "";
					for ( var i:int = 0, len:int = ary.length; i < len; i++)
					{
						data += ary[i];
					}
				}
				nextToken();
				if ( SGFUtil.match( head , "[" ) )
				{
					do
					{
						index = sgf.indexOf( "]" , sgfIndex );
						sgfIndex++;
						preStr = sgf.substr( sgfIndex , index - sgfIndex );
						data += "," + preStr;
						sgfIndex += preStr.length;
						nextToken();
					} while ( SGFUtil.match( head , "[" ) )
				}
				if ( node.isRootNode() )
				{
					if ( checkPos(head) == false )
					{
						if (head != ";" && head != "(" && head != EOF)
                        {
                            do
                            {
                                data += head;
                                nextToken();
                            }while (!checkPos(head) && head != ";" && head != "(" && head != EOF)
                        }
					}
				}
				node.addNodeProperty( prop , data );
			}
			
		}
	
	}

}